﻿using XinLife.Application.Interface;
using XinLife.Model;
using XinLife.Core.Model;
using XinLife.Core.Helper;
using XinLife.Core.Extention;
using SqlSugar;

namespace XinLife.Application.Implement
{
    public class RoleService : BaseService, IRoleService
    {
        public RoleService(IBaseRepository baseRepository) : base(baseRepository) { }

        public async Task<AjaxResult> DelRoleAsync(string ids)
        {
            string[] cIds = ids.Split(',');
            try
            {
                await _db.Ado.BeginTranAsync();

                await _db.Deleteable<Role>().Where(t => cIds.Contains(t.cId)).ExecuteCommandAsync();
                await _db.Deleteable<UserRole>().Where(t => cIds.Contains(t.cRoleId)).ExecuteCommandAsync();
                await _db.Deleteable<Authorize>().Where(t => cIds.Contains(t.cObjectId) && t.cObjectType == 1).ExecuteCommandAsync();

                await _db.Ado.CommitTranAsync();
            }
            catch (Exception ex)
            {
                await _db.Ado.RollbackTranAsync();
                throw ex;
            }
            return Success("删除成功");
        }

        public async Task<AjaxResult> EditRoleAsync(Role model)
        {
            if (string.IsNullOrWhiteSpace(model.cId))
            {
                model.Create(AspNetUser.User.cId);
                await _db.Insertable(model).ExecuteCommandAsync();
                return Success("添加成功");
            }
            else
            {
                var old = await _db.Queryable<Role>().FirstAsync(t => t.cId == model.cId);
                model.cCreatedBy = old.cCreatedBy;
                model.cCreatedDate = old.cCreatedDate;

                await _db.Updateable(model).ExecuteCommandAsync();
                return Success("修改成功");
            }
        }

        public async Task<AjaxResult> GetRoleAuthListAsync(string roleId)
        {
            var modules = await _db.Queryable<Module>().OrderBy(t => t.cSortCode).ToListAsync();
            var moduleButtons = await _db.Queryable<ModuleButton>().ToListAsync();
            var rothauth = new List<Authorize>();
            if (!string.IsNullOrWhiteSpace(roleId))
            {
                rothauth = await _db.Queryable<Authorize>().Where(t => t.cObjectId == roleId && t.cObjectType == 1).ToListAsync();
            }

            Func<List<Module>, string, List<object>> res = null;
            res = (List<Module> list, string parentid) =>
            {
                var items = list.FindAll(t => t.cParentId == parentid);

                var b = new List<object>();
                if (items.Count == 0)
                {
                    var buttons = moduleButtons.FindAll(t => t.cModuleId == parentid);
                    foreach (var item in buttons)
                    {
                        var isHas = rothauth.Exists(t => t.cItemId == item.cId);
                        b.Add(new
                        {
                            value = item.cId,
                            name = item.cTitle,
                            selected = isHas,
                            itemType = 2
                        });
                    }
                }
                else
                {
                    items.ForEach(t =>
                    {
                        bool isHas = rothauth.Exists(r => r.cItemId == t.cId);
                        b.Add(new
                        {
                            value = t.cId,
                            name = t.cTitle,
                            selected = isHas,
                            children = res(list, t.cId),
                            itemType = 1
                        });

                    });
                }

                return b;
            };
            return Success(new { info = res(modules, "0"), expandedKeys = modules.Where(t => t.cParentId == "0").Select(t => t.cId).ToList() });
        }

        public async Task<AjaxResult> GetRoleByIdAsync(string id)
        {
            var data = await _db.Queryable<Role>().InSingleAsync(id);

            return Success(data);
        }

        public async Task<object> GetRoleList()
        {
            return await _db.Queryable<Role>().Select(t => new
            {
                value = t.cId,
                label = t.cName
            }).ToListAsync();
        }

        public async Task<object> GetRolePageList(Pagination page, string queryJson)
        {
            var queryParam = queryJson.ToJObject();
            string? name = queryParam.Value<string>("name");

            RefAsync<int> totalCount = 0;
            var roles = await _db.Queryable<Role>()
                     .WhereIF(!name.IsEmpty(), a => a.cName.Contains(name))
                     .OrderBy((a) => a.cSortCode, OrderByType.Asc)//倒序
                     .ToPageListAsync(page.pageIndex, page.pageSize, totalCount);

            return new PageData<object>()
            {
                count = totalCount,
                entitys = roles
            };
        }

        public async Task<AjaxResult> SaveRoleAuth(RoleAuthInputDto roleAuthInputDto)
        {
            var role = roleAuthInputDto.MapTo<Role>();

            if (string.IsNullOrWhiteSpace(role.cId))
            {
                var data = await _db.Queryable<Role>().Where(t => t.cName == role.cName).ToListAsync();
                if (data.Count > 0)
                {
                    return Error("此角色名已存在不能重复添加");
                }
                await _db.Insertable(role).ExecuteCommandAsync();
            }
            else
            {
                var old = await _db.Queryable<Role>().InSingleAsync(role.cId);
                role.cCreatedBy = old.cCreatedBy;
                role.cCreatedDate = old.cCreatedDate;
                var data = await _db.Queryable<Role>().Where(t => t.cName == role.cName && t.cId != role.cId).ToListAsync();
                if (data.Count > 0)
                {
                    return Error("此角色名已存在不能修改");
                }
                await _db.Updateable(role).ExecuteCommandAsync();
            }

            await _db.Deleteable<Authorize>().Where(t => t.cObjectId == role.cId && t.cObjectType == 1).ExecuteCommandAsync();
            if (roleAuthInputDto.AuthLists != null)
            {
                foreach (var auth in roleAuthInputDto.AuthLists)
                {
                    var m = new Authorize()
                    {
                        cId = Guid.NewGuid().ToString(),
                        cObjectId = role.cId,
                        cObjectType = 1,
                        cItemId = auth.ItemId,
                        cItemType = auth.ItemType,
                        cCreatedBy = AspNetUser.UserId,
                        cCreatedDate = DateTime.Now
                    };
                    await _db.Insertable(m).ExecuteCommandAsync();
                }
            }
            return Success("保存成功");
        }
    }
}
